package com.funi.demo;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.funi.consts.Constants;
import lombok.extern.slf4j.Slf4j;
import org.gitlab4j.api.CommitsApi;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.Pager;
import org.gitlab4j.api.models.*;
import org.junit.Test;

import java.util.*;

/**********************************************************************
 * &lt;p&gt;文件名：Test.java &lt;/p&gt;
 * &lt;p&gt;文件描述：(描述该文件做什么)
 * @project_name：code_total
 * @author zengshunyao
 * @create 2025/5/28 17:42
 * @history
 * @department：政务事业部
 * Copyright ChengDu Funi Cloud Code Technology Development CO.,LTD 2014
 *                    All Rights Reserved.
 */
@Slf4j
public class GitLabCodeStats {

    private static final String GITLAB_URL = Constants.GITLAB_URL;
    private static final String PERSONAL_ACCESS_TOKEN = Constants.PERSONAL_ACCESS_TOKEN;

    /**
     * 测试提交
     */
    @Test
    public void test() {
        Integer PROJECT_ID = 1195; // 替换为实际项目ID
        String DEV_USERNAME = "zhaoguilin"; // 目标开发者用户名
        //时间段
        //开始时间
        String START_TIME_STR = "2025-08-01 00:00:00";
        //截止时间
        String END_TIME_STR = "2025-09-01 00:00:00";

        GitLabApi gitLabApi = new GitLabApi(GITLAB_URL, PERSONAL_ACCESS_TOKEN);
        CommitsApi commitsApi = gitLabApi.getCommitsApi();

        int totalAdded = 0;
        int totalDeleted = 0;

        try {
            // 获取开发者所有提交记录（含分页）
            Pager<Commit> commitsPager = commitsApi.getCommits(
                    PROJECT_ID,
                    null,
                    DateUtil.parse(START_TIME_STR, "yyyy-MM-dd HH:mm:ss"),
                    DateUtil.parse(END_TIME_STR, "yyyy-MM-dd HH:mm:ss"),
                    100
            );

            for (Commit commit : commitsPager.all()) {
                // 获取单次提交的差异
                List<Diff> diffs = commitsApi.getDiff(PROJECT_ID, commit.getId());
                for (Diff diff : diffs) {
                    totalAdded += Arrays.asList(diff.getDiff().split("\n")).stream()
                            .filter(line -> line.startsWith("+")).count();
                    totalDeleted += Arrays.asList(diff.getDiff().split("\n")).stream()
                            .filter(line -> line.startsWith("-")).count();
                }
            }

            System.out.println("开发者 " + DEV_USERNAME + " 在项目中的代码行数统计：");
            System.out.println("新增行数: " + totalAdded);
            System.out.println("删除行数: " + totalDeleted);

        } catch (GitLabApiException e) {
            e.printStackTrace();
        }
    }

    /**
     * 分析某个工程某段时间的代码提交记录
     *
     * @throws GitLabApiException
     */
    @Test
    public void commitList() throws GitLabApiException {
        GitLabApi gitLabApi = new GitLabApi(GITLAB_URL, PERSONAL_ACCESS_TOKEN);
        //时间段
        //开始时间
        String START_TIME_STR = "2025-08-01 00:00:00";
        //截止时间
        String END_TIME_STR = "2025-09-01 00:00:00";
        Date start = DateUtil.parse(START_TIME_STR, "yyyy-MM-dd HH:mm:ss");
        Date end = DateUtil.parse(END_TIME_STR, "yyyy-MM-dd HH:mm:ss");
        List<Commit> commitList = gitLabApi.getCommitsApi().getCommits(1195, null, start, end,
                null,
                true, false, false);
        for (Commit commit : commitList) {
            System.out.println(commit.getId() + "=" + commit.getCommitterName() + "," + commit.getCommitterEmail() + "," + commit.getAuthorName() + "," + commit.getAuthorEmail());
        }
    }

    /**
     *
     */
    @Test
    public void findPerson() {
        String name = "zhaoguilin";
        try {
            List<User> list = this.getMembers();
            for (User u : list) {
                if (Objects.equals(name, u.getName())
                        || Objects.equals(name, u.getUsername())
                        //兼顾拼音，解决刘毅和郑礼珂账号问题
                        || Objects.equals(name, u.getName())
                        || Objects.equals(name, u.getUsername())
                        //邮箱匹配
                        || Objects.equals(name, u.getEmail())) {
                    System.err.println(JSON.toJSONString(u));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取 developer 人员信息
     *
     * @return
     * @throws Exception
     */
    private List<User> getMembers() throws Exception {
        final List<User> userList = new ArrayList<>();
        final List<Project> projectList = new ArrayList<>();

        GitLabApi gitLabAPI = new GitLabApi(GITLAB_URL, PERSONAL_ACCESS_TOKEN);
        //获取所有组路径下的人员信息
        final List<Group> groupList = gitLabAPI.getGroupApi().getGroups();
        log.info("==========================================>组清单<==========================================");
        for (Group g : groupList) {
            log.info("组名称：{},组全名称：{}, 组描述：{},组路径：{}", g.getName(), g.getFullName(), g.getDescription(), g.getFullPath());
            final List<Member> members = gitLabAPI.getGroupApi().getMembers(g.getId());
            projectList.addAll(gitLabAPI.getGroupApi().getProjects(g.getId()));
            for (Member m : members) {
                if (!checkMemberExist(userList, m)) {
                    final User user = gitLabAPI.getUserApi().getUser(m.getId());
                    userList.add(user);
                }
            }
        }

        //获取所有Project下的人员信息
        log.info("==========================================>项目清单<==========================================");
        for (Project project : projectList) {
            final String projectName = project.getPath();
            final Integer projectId = project.getId();
            final String description = project.getDescription();
            final String webUrl = project.getWebUrl();
            log.info("项目名称：{}, 项目Id：{}, 项目描述：{}, 项目WEB地址：{}", projectName, projectId, description, webUrl);
            final List<Member> members = gitLabAPI.getProjectApi().getMembers(projectId);
            for (Member m : members) {
                if (!checkMemberExist(userList, m)) {
                    final User user = gitLabAPI.getUserApi().getUser(m.getId());
                    userList.add(user);
                }
            }
        }
        return userList;
    }

    /**
     * 判断人员是否已经存在
     *
     * @param userList
     * @param m
     * @return
     */
    private boolean checkMemberExist(final List<User> userList, final Member m) {
        //for (User user : userList) {
        //    if (user.getId().equals(m.getId())) {
        //        return true;
        //    }
        //}
        //return false;

        return userList.stream().anyMatch(u -> Objects.equals(u.getId(), m.getId()));
    }
}
